import multiprocessing
import types
import datetime
import os
import logging
import uploadfile


SUCCESS,\
FAILURE,\
ERROR,\
EXCEPTION =range(4)


RUNCASEPATH = 'casepath'

def Runner(queue, uploadconfig, file_name, path, taskid):
    cwd =  os.getcwd()
    file_name = os.path.join(cwd, file_name)
    runpath = os.path.join(RUNCASEPATH, path)
    if not os.path.exists(runpath):
        os.mkdir(runpath)
    os.chdir(runpath)
    
    logging.basicConfig(filename = 'task.log', 
                                format='%(asctime)s %(levelname)-8s %(message)s',
                                datefmt='%Y%b%d %H:%M:%S')
   
        
    logging.getLogger().setLevel(logging.DEBUG)
    
    logging.info('task script begin run')
    info_for_caller = {}
    
    uploadfiles = []
    uploadcasefiles = []
    
    result = None
    try:
        execfile(file_name,  globals())
        result  = globals()['main']()
        if result is None or type(result) != types.DictionaryType or not result.has_key('result'):
            raise ValueError('script return not standard')
        
        if result['result'] == True:
           info_for_caller['result'] = SUCCESS
        else:
            info_for_caller['result'] = FAILURE
        
        if result['message'] and type(result['message']) == types.StringType:
            info_for_caller['message'] = result['message']
        
        if 'uploadfile' in result and type(result['uploadfile']) == types.ListType:
            uploadfiles = result['uploadfile']
            
        if 'caseresultfile' in result and type(result['caseresultfile']) == types.ListType:
            uploadcasefiles = result['caseresultfile']
        
    except SystemExit:
        logging.warn('script should`t have system exit')
        info_for_caller['result'] = EXCEPTION
        info_for_caller['message'] = 'script should`t have system exit'
    except Exception as e:
        logging.exception(e)
        info_for_caller['result'] = EXCEPTION
        info_for_caller['message'] = str(e)
    
    try:
        uploadfiles.append('task.log')
        uploadfile.UploadFile(uploadconfig, 0, 1, uploadfiles, uploadcasefiles)
    except Exception as e:
        logging.exception(e)
    queue.put(info_for_caller)

IDLE = -1
RUN = 0
CLOSE = 1
TERMINATE = 2
EXCEPTION  = 3

class uploadconfig():
    ip ='10.20.77.43'
    port  = 21
    username = 'autotest'
    password = 'autotest'

class CaseExecuter():
    def __init__(self, info):
        self.process = None
        self.queue = None
        self.status = IDLE
        self.starttime = None
        self.endtime = None 
        self.result = None
        self.resultmessage = None
        self.info  = info
    
    def Status(self):
        return self.status
    
    
    def Start(self):
        self.queue = multiprocessing.Queue()
        self.process = multiprocessing.Process(target = Runner, args = (self.queue, 
                                                                        uploadconfig(),
                                                                        self.info.scriptname, 
                                                                        self.info.path, 
                                                                        self.info.taskid))
        
        self.process.start()
        self.status = RUN
        self.starttime = datetime.datetime.now()
        
    def Stop(self):
        assert(self.status == RUN)
        if self.process:
            if self.process.is_alive():
                self.process.terminate()
            
            self.process.join()
        self.status = TERMINATE
        self.endtime = datetime.datetime.now()
    
    def ProcessResult(self):
        pass
    
    def Finished(self):
        if self.status == CLOSE or self.status == TERMINATE or self.status == EXCEPTION:
            return True
        
        if self.process.is_alive():
            return False 
        
        if self.queue.qsize() != 1:
            self.status = EXCEPTION
            self.process.join()
            raise ValueError('queue size is not equal 1')
        
        result = self.queue.get()
        self.result = result['result']
        self.resultmessage = str(result)
        self.process.join()
        
        self.status = CLOSE
        self.endtime = datetime.datetime.now()
        return True
    
class info:
    scriptname = 'c:/script1.py'
    templateid = 1
    path = '1_2'
    taskid = 2
    args = ''
    
if __name__ == '__main__':
    Runner(None, uploadconfig(), info.scriptname, info.path, info.taskid)
    cr = CaseExecuter(info)
    cr.Start()
    while (cr.Finished() == False):
        pass
    print((cr.endtime - cr.starttime).seconds)
    print(cr.result)
    print('ok')
            